package com.core.util;

import org.slf4j.Logger;
import java.util.StringJoiner;

/**
 * 日志工具类，基于 SLF4J 封装
 * 主要特点：
 * 1. 统一日志前缀（[MyAppLog]）
 * 2. 支持结构化日志参数，传入 key-value 键值对，格式化为 {key=value, key2=value2}
 * 3. 支持 info、debug、error 等日志级别打印
 * 4. error 方法支持异常堆栈打印
 * 5. 提供根据 Class 获取 Logger 的便捷方法
 * @author hc
 * @CreateTime 2025/7/29 15:08
 */
public class LogUtil {
    // 日志统一前缀，可根据项目名或模块名修改
    private static final String LOG_PREFIX = "[CommandApp] ";

    /**
     * 输出 info 级别日志（可变参数方式）
     *
     * @param logger  SLF4J 的 Logger 实例
     * @param message 日志消息模板（如："User {} logged in"）
     * @param args    参数（会替换 message 中的 {}）
     */
    public static void info(Logger logger, String message, Object... args) {
        if (logger.isInfoEnabled()) {
            logger.info(LOG_PREFIX + message, args);
        }
    }

    /**
     * 输出 debug 级别日志
     *
     * @param logger  Logger 实例
     * @param message 日志消息
     * @param args    参数
     */
    public static void debug(Logger logger, String message, Object... args) {
        if (logger.isDebugEnabled()) {
            logger.debug(LOG_PREFIX + "{}", message, args);
        }
    }

    /**
     * 输出 error 级别日志（附带异常堆栈）
     *
     * @param logger  Logger 实例
     * @param message 日志消息
     * @param t       异常对象
     * @param args    参数
     */
    public static void error(Logger logger, String message, Throwable t, Object... args) {
        if (logger.isErrorEnabled()) {
            logger.error(LOG_PREFIX + "{}", message, args, t);
        }
    }

    /**
     * 以 key-value 的形式输出 info 级别结构化日志
     *
     * @param logger     Logger 实例
     * @param message    主消息
     * @param keyValues  key-value 键值对，必须为偶数个
     */
    public static void infoKV(Logger logger, String message, Object... keyValues) {
        if (logger.isInfoEnabled()) {
            String structured = LOG_PREFIX + message + " " + formatKV(keyValues);
            logger.info(structured);
        }
    }

    /**
     * 将 key-value 键值对格式化为结构化字符串，形如：{key1=value1, key2=value2}
     *
     * @param keyValues 键值对
     * @return 格式化后的字符串
     */
    private static String formatKV(Object... keyValues) {
        if (keyValues == null || keyValues.length == 0) {
            return "";
        }
        if (keyValues.length % 2 != 0) {
            throw new IllegalArgumentException("keyValues length must be even");
        }

        StringJoiner sj = new StringJoiner(", ", "{", "}");
        for (int i = 0; i < keyValues.length; i += 2) {
            Object key = keyValues[i];
            Object value = keyValues[i + 1];
            sj.add(key + "=" + value);
        }
        return sj.toString();
    }

    /**
     * 获取当前类的 Logger 实例（推荐用于静态注入）
     *
     * @param clazz 当前类
     * @return SLF4J Logger 实例
     */
    public static Logger getLogger(Class<?> clazz) {
        return org.slf4j.LoggerFactory.getLogger(clazz);
    }
}
